package com.hanwei.uap.common.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 日期工具类
 *
 * @author zhaoam
 * @create 2017-08-07 20:31
 **/
public class DateUtil {
    public static final String DF_ALL23 = "yyyy-MM-dd HH:mm:ss SSS";
    public static final String DF_ALL19 = "yyyy-MM-dd HH:mm:ss";
    public static final String DF_APP10 = "yyyy-MM-dd";
    public static final String DF_APP6 = "yyMMdd";
    public static final String DF_APP8 = "yyyyMMdd";
    public static final String DF_HMSS12 = "HH:mm:ss SSS";
    public static final String DF_HMS6 = "HHmmss";
    public static final String DF_HMS9 = "HHmmssSSS";
    public static final String DF_HMS8 = "HH:mm:ss";
    public static final String DF_HMS8D = "HH.mm.ss";
    public static final String DF_SALL14 = "yyyyMMddHHmmss";
    public static final String DF_SALL17 = "yyyyMMddHHmmssSSS";
    public static final String DF_SN15 = "yyMMddHHmmssSSS";

    public static String getCurrentDate(String format) {
        return new SimpleDateFormat(format).format(getCurrentDate());
    }

    public static Date getCurrentDate() {
        return new Date();
    }

    public static String getCurDate() {
        return new SimpleDateFormat(DF_APP10).format(getCurrentDate());
    }

    /**
     * 获取当前时间的字符串格式yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static String getCurrentTime() {
        return new SimpleDateFormat(DF_ALL19).format(getCurrentDate());
    }

    public static String formatDate(String format, Date date) {
        return new SimpleDateFormat(format).format(date);
    }

    public static String formatDF10(Date date) {
        return formatDate(DF_APP10, date);
    }

    public static String formatDF19(Date date) {
        return formatDate(DF_ALL19, date);
    }

    public static Date parseDF19(String date) {
        try {
            return new SimpleDateFormat(DF_ALL19).parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date parseDate(String date, String format) {
        try {
            return new SimpleDateFormat(format).parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String formatDF19(Date date, String nullval) {
        if (null == date)
            return nullval;
        else
            return formatDate(DF_ALL19, date);
    }

    public static String formatDF10(Date date, String nullval) {
        if (null == date)
            return nullval;
        else
            return formatDate(DF_APP10, date);
    }

    public static String formatFromDF19ToDF14(String time) {
        Date date = parseDate(time, DateUtil.DF_ALL19);
        return formatDate(DateUtil.DF_SALL14, date);
    }

    /**
     * 对时间的指定字段进行加减yyyy-MM-dd 00:00:00
     *
     * @return
     */
    public static String addTime(String time, int field, int amount) {
        Date date = DateUtil.parseDate(time, DF_ALL19);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(field, amount);
        return DateUtil.formatDF19(calendar.getTime());
    }

    /**
     * 对日期的指定字段进行加减操作
     *
     * @param date 要加减的日期
     * @param field 要加减的字段
     * @param amount 要加减的数量
     * @return
     */
    public static Date addDate(Date date, int field, int amount) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(field, amount);
        return c.getTime();
    }

    public static String getFirstDayTimeOfMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return DateUtil.formatDF19(calendar.getTime());
    }

    public static String getLatestDayTime(String time) {
        Date date = DateUtil.parseDate(time, DF_ALL19);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return DateUtil.formatDF19(calendar.getTime());
    }

    public static String getLatestDayTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return DateUtil.formatDF19(calendar.getTime());
    }

    public static String getNextDayTime(String time) {
        Date date = DateUtil.parseDate(time, DF_ALL19);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_YEAR, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return DateUtil.formatDF19(calendar.getTime());
    }

    public static String getLastDayTime(String time) {
        Date date = DateUtil.parseDate(time, DF_ALL19);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_YEAR, -1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return DateUtil.formatDF19(calendar.getTime());
    }

    public static String getLastDayTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_YEAR, -1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return DateUtil.formatDF19(calendar.getTime());
    }

    /**
     * 获取每一月开始的第一个1小时时间点yyyy-MM-01 00:00:00
     *
     * @return
     */
    public static String getFirstHourTimeOfMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return DateUtil.formatDF19(calendar.getTime());
    }

    /**
     * 获取一个时间最近的1小时时间点
     *
     * @param time 格式：yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static String getLatestHourTime(String time) {
        Date date = DateUtil.parseDate(time, DF_ALL19);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return DateUtil.formatDF19(calendar.getTime());
    }

    /**
     * 获取最近的1小时时间点
     *
     * @return
     */
    public static String getLatestHourTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return DateUtil.formatDF19(calendar.getTime());
    }

    /**
     * 获取一个时间上一个1小时时间点
     *
     * @param time 格式：yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static String getLastHourTime(String time) {
        Date date = DateUtil.parseDate(time, DF_ALL19);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR_OF_DAY, -1);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return DateUtil.formatDF19(calendar.getTime());
    }

    /**
     * 获取一个时间最近的下一个小时时间点
     *
     * @param time 格式：yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static String getNextHourTime(String time) {
        Date date = DateUtil.parseDate(time, DF_ALL19);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR_OF_DAY, 1);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return DateUtil.formatDF19(calendar.getTime());
    }

    /**
     * 获取每一月开始的第一个五分钟时间点yyyy-MM-01 00:00:00
     *
     * @return
     */
    public static String getFirstMin5TimeOfMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return DateUtil.formatDF19(calendar.getTime());
    }

    /**
     * 获取一个时间向前最近的五分钟时间点
     *
     * @param time 格式：yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static String getLatestMin5Time(String time) {
        Date date = DateUtil.parseDate(time, DF_ALL19);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int min = calendar.get(Calendar.MINUTE);
        int num = min % 5;
        calendar.add(Calendar.MINUTE, num * (-1));
        calendar.set(Calendar.SECOND, 0);
        return DateUtil.formatDF19(calendar.getTime());
    }

    /**
     * 获取当前时间向前最近的五分钟时间点
     *
     * @return
     */
    public static String getLatestMin5Time() {
        Calendar calendar = Calendar.getInstance();
        int min = calendar.get(Calendar.MINUTE);
        int num = min % 5;
        calendar.add(Calendar.MINUTE, num * (-1));
        calendar.set(Calendar.SECOND, 0);
        return DateUtil.formatDF19(calendar.getTime());
    }

    /**
     * 获取一个时间上上一个五分钟时间点
     *
     * @param time 格式：yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static String getLastMin5Time(String time) {
        Date date = DateUtil.parseDate(time, DF_ALL19);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int min = calendar.get(Calendar.MINUTE);
        int num = min % 5;
        calendar.add(Calendar.MINUTE, num * (-1) - 5);
        calendar.set(Calendar.SECOND, 0);
        return DateUtil.formatDF19(calendar.getTime());
    }

    /**
     * 获取当前时间上上一个五分钟时间点
     *
     * @return
     */
    public static String getLastMin5Time() {
        Calendar calendar = Calendar.getInstance();
        int min = calendar.get(Calendar.MINUTE);
        int num = min % 5;
        calendar.add(Calendar.MINUTE, num * (-1) - 5);
        calendar.set(Calendar.SECOND, 0);
        return DateUtil.formatDF19(calendar.getTime());
    }

    /**
     * 获取一个时间最近的下一个五分钟时间点
     *
     * @param time 格式：yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static String getNextMin5Time(String time) {
        Date date = DateUtil.parseDate(time, DF_ALL19);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int min = calendar.get(Calendar.MINUTE);
        int num = min % 5;
        calendar.add(Calendar.MINUTE, 5 - num);
        calendar.set(Calendar.SECOND, 0);
        return DateUtil.formatDF19(calendar.getTime());
    }

    /**
     * 取得某月的的最后一天
     *
     * @param year
     * @param month
     * @return
     */
    public static Date getLastDayOfMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);// 年
        cal.set(Calendar.MONTH, month - 1);// 月，因为Calendar里的月是从0开始，所以要减1
        cal.set(Calendar.DAY_OF_MONTH, 1);// 日，设为一号
        cal.add(Calendar.MONTH, 1);// 月份加一，得到下个月的一号
        cal.add(Calendar.DAY_OF_MONTH, -1);// 下一个月减一为本月最后一天
        return cal.getTime();// 获得月末是几号
    }

    /**
     * 取得下月的第一天
     *
     * @return
     */
    public static String getFirstDayOfNextMonth() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MONTH, 1);// 月份加一，得到下个月的一号
        cal.set(Calendar.DAY_OF_MONTH, 1);// 日，设为一号
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        return DateUtil.formatDF19(cal.getTime());
    }

    /**
     * 取得下月的第一天
     *
     * @param date
     * @return
     */
    public static Date getFirstDayOfNextMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, 1);// 月份加一，得到下个月的一号
        cal.set(Calendar.DAY_OF_MONTH, 1);// 日，设为一号
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        return cal.getTime();
    }

    /**
     * 取得某天是一年中的多少周
     *
     * @param date
     * @return
     */
    public static int getWeekOfYear(Date date) {
        Calendar c = Calendar.getInstance();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setMinimalDaysInFirstWeek(7);
        c.setTime(date);
        return c.get(Calendar.WEEK_OF_YEAR);
    }

    /**
     * 取得某天所在周的第一天
     *
     * @param date
     * @return
     */
    public static Date getFirstDayOfWeek(Date date) {
        Calendar c = Calendar.getInstance();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setTime(date);
        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
        return c.getTime();
    }

    /**
     * 取得某天所在周的最后一天
     *
     * @param date
     * @return
     */
    public static Date getLastDayOfWeek(Date date) {
        Calendar c = Calendar.getInstance();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setTime(date);
        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek() + 6);
        return c.getTime();
    }

    /** */
    /**
     * 取得某一年共有多少周
     *
     * @param year
     * @return
     */
    public static int getMaxWeekNumOfYear(int year) {
        Calendar c = Calendar.getInstance();
        c.set(year, Calendar.DECEMBER, 31, 23, 59, 59);
        return getWeekOfYear(c.getTime());
    }

    /**
     * 获取某一年某一周中的日期
     *
     * @param year
     * @param week
     * @return
     * @description
     */
    public static List<String> getWeekDays(int year, int week) {
        List<String> list = new ArrayList<String>();
        Date date = getFirstDayOfWeek(year, week);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        for (int i = 0; i < 7; i++) {
            list.add(formatDate(DF_APP10, calendar.getTime()));
            calendar.add(Calendar.DAY_OF_YEAR, 1);
        }
        return list;
    }

    /**
     * 取得某年某周的第一天 对于交叉:2008-12-29到2009-01-04属于2008年的最后一周,2009-01-05为2009年第一周的第一天
     *
     * @param year
     * @param week
     * @return
     */
    public static Date getFirstDayOfWeek(int year, int week) {
        Calendar calFirst = Calendar.getInstance();
        calFirst.set(year, 0, 7);
        Date firstDate = getFirstDayOfWeek(calFirst.getTime());

        Calendar firstDateCal = Calendar.getInstance();
        firstDateCal.setTime(firstDate);

        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, year);
        c.set(Calendar.MONTH, Calendar.JANUARY);
        c.set(Calendar.DATE, firstDateCal.get(Calendar.DATE));

        Calendar cal = (Calendar) c.clone();
        cal.add(Calendar.DAY_OF_YEAR, (week - 1) * 7);
        firstDate = getFirstDayOfWeek(cal.getTime());

        return firstDate;
    }

    /**
     * 取得某年某周的最后一天 对于交叉:2008-12-29到2009-01-04属于2008年的最后一周
     * 2009-01-04为2008年最后一周的最后一天
     *
     * @param year
     * @param week
     * @return
     */
    public static Date getLastDayOfWeek(int year, int week) {
        Calendar calLast = Calendar.getInstance();
        calLast.set(year, 0, 7);
        Date lastDate = getLastDayOfWeek(calLast.getTime());

        Calendar lastDateCal = Calendar.getInstance();
        lastDateCal.setTime(lastDate);

        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, year);
        c.set(Calendar.MONTH, Calendar.JANUARY);
        c.set(Calendar.DATE, lastDateCal.get(Calendar.DATE));

        Calendar cal = (Calendar) c.clone();
        cal.add(Calendar.DAY_OF_YEAR, (week - 1) * 7);
        lastDate = getLastDayOfWeek(cal.getTime());

        return lastDate;
    }

    public static String getYYYYMM(Date date) {
        if (null != date) {
            return formatDate("yyyyMM", date);
        }
        return null;
    }

    public static String getCurYYYYMM() {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        return year + (month > 9 ? "" : "0") + month;
    }

    public static String getCurYYYY() {
        return formatDate("yyyy", getCurrentDate());
    }

    public static String getLastYYYYMM() {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        return year + (month > 9 ? "" : "0") + month;
    }

    public static String getYYYYMM(String time) {
        Date date = parseDF19(time);
        return getYYYYMM(date);
    }

    public static boolean isValidDate(String format, String date) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        try {
            sdf.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
}
